package cn.bonoon.kernel.support.searcher;

import cn.bonoon.kernel.descriptors.DescriptorFactory;
import cn.bonoon.kernel.descriptors.EntityDescriptor;
import cn.bonoon.kernel.support.ProxyEntityManager;
import cn.bonoon.kernel.support.entities.Persistable;

/**
 * <pre>
 * 一个searcher对应一个<code>entityClass</code>类型的查询操作；
 * 对<code>entityClass</code>解析后确定该<code>entityClass</code>的一些固定的查询条件，
 * 如：deleted=false/order by x.ordinal等
 * 
 * 创建后必须使用{@link #init()}初始化函数来进行初始化，以后是不允许再调该初始化函数的
 * </pre>
 * @author jackson
 *
 */
public class BaseSearcher {
	
	/**
	 * <pre>
	 * 是否有order by的限制，如果有，则其它的排序将无法起效
	 * 
	 * 如果order为null，则表示允许追加排序语句
	 * 
	 * 这三个值由实体解析出来的固定值，当searcher生成后，这几值不应该被改变
	 * </pre>
	 */
	protected final String order, where, from;
    
    protected final Class<? extends Persistable> entityClass;
    
	protected final EntityDescriptor entityDescriptor;

//	private volatile boolean initialized = false;
	public BaseSearcher(Class<? extends Persistable> entityClass){
		this.entityClass = entityClass;
		this.entityDescriptor = DescriptorFactory.entityDescriptor(entityClass);
		this.from = " from " + entityClass.getName() + " x ";
		
		if(entityDescriptor.is(EntityDescriptor.MOVABLE)){
			order = "x.ordinal asc";
		}else{
			order = null;
		}
		
		if(entityDescriptor.is(EntityDescriptor.DELETABLE)){
			where = " where x.deleted=false";
		}else{
			where = " where 1=1";
		}
	}
	
	public EntityDescriptor getEntityDescriptor() {
		return entityDescriptor;
	}
	
	public void init(){
//		if(!initialized){
//			initialized = true;
//		}
	}
	
	protected StandardFinder initFinder(StandardFinder finder){
		finder.from.append(from);
		finder.where.append(where);
		if(null != order){
			finder.allowAppendOrder = false;
			finder.orderby.append(order);
		}
		return finder;
	}
	
	public StandardFinder finder(ProxyEntityManager manager){
		return initFinder(new StandardFinder(manager));
	}
	
	public String orderby(){
		if(null != order){
			return " order by " + (order.trim().isEmpty() ? "x.id desc" : order);
		}
		return "";
	}
	
	public String allEntities(){
		return from + where;// + " order by " + order;
	}
	
	public String treeRoot(){
		return from + where + " and x.parent is null";// order by " + order;
	}
	
	public String treeChildren(){
		return from + where + " and x.parent.id=?";// order by " + order;
	}
}
